using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using IndieStudio.BugsBang.Utility;
using UnityEngine.Events;

///Developed By Indie Studio
///https://assetstore.unity.com/publishers/9268
///www.indiestd.com
///info@indiestd.com

namespace IndieStudio.BugsBang.Game
{
	/* List of UI Events */
	[DisallowMultipleComponent]
	public class UIEvents : MonoBehaviour
	{
		/// <summary>
		/// A static instance of this class.
		/// </summary>
		public static UIEvents instance;

		/// <summary>
		/// A Unity event.
		/// </summary>
		private UnityEvent unityEvent = new UnityEvent ();

		//Set of dialogs
		private Dialog resetGameConfirmDialog;
		private Dialog playConfirmDialog;
		private Dialog renewBoosterDialog;
		private Dialog noLivesDialog;
		private Dialog noTimeDialog;
		private Dialog exitConfirmDialog;
		private Dialog leaveConfirmDialog;
		private Dialog lockedDialog;
		private Dialog levelsCompletedDialog;

		void Awake ()
		{
			//Setting up the references

			if (instance == null) {
				instance = this;
			}

			GameObject temp;

			temp = GameObject.Find ("ResetGameConfirmDialog");
			if (temp != null) {
				resetGameConfirmDialog = temp.GetComponent<Dialog> ();
				resetGameConfirmDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("PlayConfirmDialog");
			if (temp != null) {
				playConfirmDialog = temp.GetComponent<Dialog> ();
				playConfirmDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("ExitConfirmDialog");
			if (temp != null) {
				exitConfirmDialog = temp.GetComponent<Dialog> ();
				exitConfirmDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("LeaveConfirmDialog");
			if (temp != null) {
				leaveConfirmDialog = temp.GetComponent<Dialog> ();
				leaveConfirmDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("LockedDialog");
			if (temp != null) {
				lockedDialog = temp.GetComponent<Dialog> ();
				lockedDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("RenewBoosterDialog");
			if (temp != null) {
				renewBoosterDialog = temp.GetComponent<Dialog> ();
				renewBoosterDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("NoLivesDialog");
			if (temp != null) {
				noLivesDialog = temp.GetComponent<Dialog> ();
				noLivesDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("NoTimeDialog");
			if (temp != null) {
				noTimeDialog = temp.GetComponent<Dialog> ();
				noTimeDialog.SetActiveFalse ();
			}

			temp = GameObject.Find ("LevelsCompletedDialog");
			if (temp != null) {
				levelsCompletedDialog = temp.GetComponent<Dialog> ();
				levelsCompletedDialog.SetActiveFalse ();
			}
		}

		public void LoadMainScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("Main"));
		}

		public void LoadHowToPlayScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("HowToPlay"));
		}

		public void LoadMissionsScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("Missions"));
		}

		public void LoadSettingsScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("Settings"));
		}

		public void LoadAboutScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("About"));
		}

		public void LoadLevelsScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("Levels"));
		}

		public void LoadGameScene ()
		{
			AudioSources.instance.PlayButtonClickSFX ();
			StartCoroutine (SceneLoader.instance.LoadScene ("Game"));
		}

		public void ShowResetGameConfirmDialog ()
		{
			//Show advertisment
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_SHOW_RESET_GAME_DIALOG, null);
			resetGameConfirmDialog.Show (true);
		}

		public void ShowPlayConfirmDialog (int levelID)
		{
			if (!(levelID > 0 && levelID <= LevelsManager.instance.levels.Count)) {
				Debug.LogWarning ("Level " + levelID + " is not defined in Levels Manager");
				return;
			}

			Level.SelectedLevelID = levelID;

			//Set the level title in the dialog
			playConfirmDialog.transform.Find ("Title").Find ("Text").GetComponent<Text> ().text = "LEVEL " + CommonUtil.IntToString (levelID);

			//Create the targets of the level inside the dialog
			Transform targets = playConfirmDialog.transform.Find ("Targets");

			playConfirmDialog.transform.localScale = Vector3.one;

			foreach (Transform child in targets) {
				Destroy (child.gameObject);
			}
				
			if (LevelsManager.instance.GetCurrentLevel ().targets.Count == 0) {
				Debug.LogWarning ("Level " + levelID + " has zero targets in the Levels Manager");
			}

			for (int i = 0; i < LevelsManager.instance.GetCurrentLevel ().targets.Count; i++) {
				PathObject po = LevelsManager.instance.GetCurrentLevel ().targets [i].pathObject;

				if (po == null) {
					continue;
				}
				Transform targetStage = CommonUtil.CreateTargetUI (PrefabsManager.instance.targetStagePrefab, targets, po.gameObject);
				targetStage.Find ("Counter").Find ("Text").GetComponent<Text> ().text = LevelsManager.instance.GetCurrentLevel ().targets [i].count.ToString ();
			}

			//Set stars rating
			Transform starOne = playConfirmDialog.transform.Find ("Stars").Find ("StarOne");
			Transform starTwo = playConfirmDialog.transform.Find ("Stars").Find ("StarTwo");
			Transform starThree = playConfirmDialog.transform.Find ("Stars").Find ("StarThree");
			CommonUtil.SetStarsRating (LevelsManager.instance.GetCurrentLevel ().starsNumber, starOne, starTwo, starThree);

			//Set level's score
			playConfirmDialog.transform.Find ("Score").Find ("ScoreValue").GetComponent<Text> ().text = "SCORE : " + LevelsManager.instance.GetCurrentLevel ().score;

			//Show advertisment
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_SHOW_Play_CONFIRM_GAME_DIALOG, null);

			//Display the dialog
			playConfirmDialog.Show (true);
		}

		public void ShowExitConfirmDialog ()
		{
			//Show advertisment
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_SHOW_EXIT_DIALOG, null);
			exitConfirmDialog.Show (true);
		}

		public void ShowLeaveConfirmDialog ()
		{
			if (!GameManager.instance.IsRunning ()) {
				return;
			}
			//Show advertisment
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_SHOW_LEAVE_DIALOG, null);
			leaveConfirmDialog.Show (true);
			GameManager.instance.Pause ();
		}

		public void ShowTimeOutDialog ()
		{
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_SHOW_TIMEOUT_DIALOG, null);
			AudioSources.instance.PlayAWWSFX ();
			noTimeDialog.Show (false);
			Debug.Log ("Show Timeout dialog");
		}

		public void ShowRenewBoosterDialog (Booster booster, Sprite boosterSprite)
		{
			GameManager.instance.Pause ();
			renewBoosterDialog.Show (false);
			renewBoosterDialog.transform.Find ("Booster").GetComponent<Image> ().sprite = boosterSprite;
			renewBoosterDialog.transform.Find ("YesButton").GetComponent<Button> ().onClick.AddListener (() => RenewBooster (booster));
		}

		public void ShowNoLivesDialog ()
		{
			AudioSources.instance.PlayAWWSFX ();
			GameManager.instance.Pause ();
			noLivesDialog.Show (false);
		}

		public void ShowLevelsCompletedDialog(){
			//Show advertisment
			AudioSources.instance.PlayCompletedSFX();
			AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_ALL_LEVELS_COMPLETE_DIALOG, null);
			levelsCompletedDialog.Show (true);
		}

		public void CloseLockedDialog ()
		{
			lockedDialog.Hide (true);
		}

		public void ResetGameConfirmDialogEvent (GameObject value)
		{
			if (value == null) {
				return;
			}

			if (value.name.Equals ("YesButton")) {
				Debug.Log ("Reset Game Confirm Dialog : Yes button clicked");
				DataManager.ResetGame ();
			} else if (value.name.Equals ("NoButton")) {
				Debug.Log ("Reset Game Confirm Dialog : No button clicked");
			}
			resetGameConfirmDialog.Hide (true);
		}

		public void ExitConfirmDialogEvent (GameObject value)
		{
			if (value.name.Equals ("YesButton")) {
				Debug.Log ("Exit Confirm Dialog : Yes button clicked");
				Application.Quit ();
			} else if (value.name.Equals ("NoButton")) {
				Debug.Log ("Exit Confirm Dialog : No button clicked");
			}
			exitConfirmDialog.Hide (true);
		}

		public void OpenLink (string link)
		{
			AudioSources.instance.PlayButtonClickSFX ();

			if (string.IsNullOrEmpty (link)) {
				return;
			}
			Application.OpenURL (link);
		}

		public void RateUsButtonEvent (string appID)
		{
			AudioSources.instance.PlayButtonClickSFX ();

			#if UNITY_ANDROID
			Application.OpenURL ("http://play.google.com/store/apps/details?id=" + appID);
			#elif UNITY_IPHONE
			Application.OpenURL("itms-apps://itunes.apple.com/app/"+appID);
			#endif
		}

		public void GameNextButtonEvent ()
		{
			GameManager.instance.NextLevel ();
		}

		public void GameBackButtonEvent ()
		{
			GameManager.instance.PreviousLevel ();
		}

		public void PauseButtonEvent ()
		{
			GameManager.instance.Pause ();
		}

		public void ResumeGameButtonEvent ()
		{
			GameManager.instance.Resume ();
		}

		public void WinDialogNextButtonEvent ()
		{
			if (Level.SelectedLevelID == LevelsManager.instance.levels.Count) {
				LoadLevelsScene ();
				return;
			}

			GameManager.instance.NextLevel ();
		}

		public void NoLivesDialogYesButtonEvent (Booster booster)
		{
			if (booster == null) {
				return;
			}

			//If there are no lives
			if (booster.GetValue () == 0) {

				//Set yes button of the dialog as interactable false
				noLivesDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = false;

				//Show ads, renew live booster value ,run game manager, use one live ,hide dialog
				unityEvent.RemoveAllListeners ();
				unityEvent.AddListener (() => booster.ResetValue ());
				unityEvent.AddListener (() => GameManager.instance.Resume ());
				unityEvent.AddListener (() => LivesIncBoosterEvent (booster));
				unityEvent.AddListener (() => noLivesDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = true);
				unityEvent.AddListener (() => noLivesDialog.Hide (false));
				unityEvent.AddListener (() => AudioSources.instance.PlayIncreaseSFX ());
			
				AdsManager.instance.ShowAdvertisment (AdPackage.AdEvent.Event.ON_RENEW_BOOSTER, unityEvent);
			} else {//If there is one live at least
				GameManager.instance.Resume ();
				LivesIncBoosterEvent (booster);
				noLivesDialog.Hide (false);
			}
		}

		public void NoTimeDialogYesButtonEvent ()
		{
			//Set yes button of the dialog as interactable false
			noTimeDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = false;

			unityEvent.RemoveAllListeners ();
			unityEvent.AddListener (() => Timer.instance.IncreaseTime (2));
			unityEvent.AddListener (() =>	GameManager.instance.Resume ());
			unityEvent.AddListener (() => noTimeDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = true);
			unityEvent.AddListener (() =>	noTimeDialog.Hide (false));

            AdsManager.instance.ShowAdvertisment(AdPackage.AdEvent.Event.ON_RENEW_BOOSTER, unityEvent);
		}

		public void TimePauseBoosterClick (Booster booster)
		{
			if (booster == null || !GameManager.instance.IsRunning ()) {
				return;
			}

			ImageFill imageFill = booster.references [0].GetComponent<ImageFill> ();

			//Check size if zero , then show dialog
			if (imageFill.isRunning) {
				return;
			}

			if (booster.GetValue () == 0) {
				AudioSources.instance.PlayLockedSFX ();
				ShowRenewBoosterDialog (booster, GameManager.instance.boosterSprites [0]);
				Debug.Log ("Show Time Puase Dialog");
				return;
			}

			booster.DecreaseValue ();

			imageFill.Run ();
			if (Timer.instance != null)
				Timer.instance.Pause ();
			Paths.instance.PausePaths ();
		}

		public void TargetsBangBoosterClick (Booster booster)
		{
			if (booster == null || !GameManager.instance.IsRunning ()) {
				return;
			}

			if (booster.GetValue () == 0) {
				AudioSources.instance.PlayLockedSFX ();
				ShowRenewBoosterDialog (booster, GameManager.instance.boosterSprites [1]);
				Debug.Log ("Show Targets Bang Dialog");
				return;
			}

			bool targetsDestroyed = false;
			int bangCount = 0;
			foreach (PathObject po in Paths.instance.pathObjectPool) {
				if (po.isTarget && !po.IsDestroying ()) {
					bangCount++;
					targetsDestroyed = true;
					po.OnHit (PathObject.DestroyMode.RAY, GameManager.instance.destroyEffects, false);
				}

				//Set bang limit to 8 as max
				if (bangCount == 8) {
					break;
				}
			}

			if (targetsDestroyed) {
				booster.DecreaseValue ();
				AudioSources.instance.PlayKillBoosterSFX ();
			}
		}

		public void LivesIncBoosterEvent (Booster booster)
		{
			if (booster == null || !GameManager.instance.IsRunning ()) {
				return;
			}

			if (booster.GetValue () == 0) {
				AudioSources.instance.PlayLockedSFX ();
				ShowRenewBoosterDialog (booster, GameManager.instance.boosterSprites [2]);
				Debug.Log ("Show Lives Inc Dialog");
				return;
			}

			if (GameManager.instance.currentLives == LevelsManager.instance.GetCurrentLevel ().lives) {
				return;
			}

			booster.DecreaseValue ();
			GameManager.instance.currentLives++;
			GameManager.instance.SetLivesFillValue (GameManager.instance.currentLives);
		}

		private void RenewBooster (Booster booster)
		{
			if (booster == null) {
				return;
			}

			GameManager.instance.Resume ();
			renewBoosterDialog.Hide (false);

			//Set yes button of the dialog as interactable false
			renewBoosterDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = false;

			//Renew booster value when the Ad is sucessfully appeared
			unityEvent.RemoveAllListeners ();
			unityEvent.AddListener (() => booster.ResetValue ());
			unityEvent.AddListener (() => AudioSources.instance.PlayIncreaseSFX ());
			unityEvent.AddListener (() => renewBoosterDialog.transform.Find ("YesButton").GetComponent<Button> ().interactable = true);

            AdsManager.instance.ShowAdvertisment(AdPackage.AdEvent.Event.ON_RENEW_BOOSTER, unityEvent);
		}

		void OnDestroy(){
			unityEvent.RemoveAllListeners ();
		}
	}
}